<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .box1{width: 100px;height: 100px;background-color: red;position: absolute;left: 0;top:0;}
    .box2{width: 100px;height: 100px;background-color: green;position: absolute;left: 0;top:110px;}
    .line{width: 1px;height: 500px;background: black;position: absolute;left: 500px;top:0;}
  </style>
</head>
<body>
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="line"></div>
</body>
<script>

  const box1 = document.querySelector(".box1")
  const box2 = document.querySelector(".box2")
  
  box2.onclick = function(){
    move(box1, {left:500}, ()=>{
      // box1.style.background = "blue"
      // box2.style.background = "blue"
      move(box1, {top:500}, ()=>{
        move(box1, {left:0}, ()=>{
          move(box2, {top:0})
        })
      })
    })
  }


  // 新增第三个参数（可选），用于接收一个回调函数，在动画结束后执行
  function move(ele, data, cb){
    if(ele.t) return;
    ele.t = setInterval(()=>{
      let flag = true;
      for(let attr in data){
        const now = parseInt(getStyle(ele, attr));
        
        let speed = (data[attr] - now)/8;
        speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
        
        ele.style[attr] = now + speed + "px";

        if(now !== data[attr]) flag = false;
      }
      if(flag){
        clearInterval(ele.t);
        ele.t = undefined;
        // 先判断是否传入回调函数，如果传入，在清除计时器后，执行该回调函数
        cb && cb();
      }
    }, 30)
  }
  
  function getStyle(ele, attr){
    return ele.currentStyle ? ele.currentStyle[attr] : getComputedStyle(ele)[attr];
  }

  // 要求：理解逻辑，会使用

  // 示例：move(元素, 配置对象, 回调函数)
    // 元素，要运动的元素，运动源
    // 配置对象的键，表示要运动的属性
    // 配置对象的值，表示要运动的属性的目标
    // 回调函数，表示动画结束后，要执行的功能


  </script>
</html>